package com.econ.powercloud.ems.service.biz.scene;

import com.econ.powercloud.common.base.facade.util.JacksonUtil;
import com.econ.powercloud.ems.common.enums.TableType;
import com.econ.powercloud.ems.dal.entity.ExtIotScene;
import com.econ.powercloud.ems.dal.entity.ExtIotViceConfig;
import com.econ.powercloud.ems.dal.entity.ext.SceneCalculation;
import com.econ.powercloud.ems.dal.entity.ext.SceneProduct;
import com.econ.powercloud.ems.dal.entity.ext.SceneStructure;
import com.econ.powercloud.ems.pojo.scene.OpenApiSceneCalculationVO;
import com.econ.powercloud.ems.pojo.scene.OpenApiSceneProductVO;
import com.econ.powercloud.ems.pojo.scene.OpenApiSceneStructureVO;
import com.econ.powercloud.ems.service.dao.*;
import com.econ.powercloud.ems.util.TransformUtil;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ Description:
 * @ Author：hgp
 * @ Create:2022-05-27-15:03
 */
@Service
public class SceneBizService {
    @Autowired
    private ExtIotSceneDAO extIotSceneDAO;
    @Autowired
    private ExtIotSceneStructureDAO extIotSceneStructureDAO;
    @Autowired
    private ExtIotViceProductDAO extIotViceProductDAO;
    @Autowired
    private ExtIotViceCalculationDAO extIotViceCalculationDAO;
    @Autowired
    private ExtIotViceConfigDAO extIotViceConfigDAO;

    /**
     * @Description: 获取场景结构图
     * @Param: [sceneCode, applicationCode]
     * @Return:
     */
    public List<OpenApiSceneStructureVO> getSceneStructure(String sceneCode, String applicationCode) {
        ExtIotScene scene = extIotSceneDAO.selectBySceneCodeAndApplicationCode(sceneCode, applicationCode);
        Assert.notNull(scene, "场景不存在！");
        List<SceneStructure> sceneStructures = extIotSceneStructureDAO.selectSceneStructureListBySceneCode(sceneCode);
        if (CollectionUtils.isEmpty(sceneStructures)) {
            return Collections.EMPTY_LIST;
        }
        Map<Integer, String> nodeMap = sceneStructures.stream().collect(Collectors.toMap(SceneStructure::getPid, SceneStructure::getNodeId));
        sceneStructures.stream().forEach(d -> d.setParentNodeId(nodeMap.get(d.getParentid())));
        List<OpenApiSceneStructureVO> result = Lists.newArrayList();
        //获取结构图的根节点
        List<SceneStructure> firstStructureList = sceneStructures.stream().filter(d -> d.getParentid() == null).collect(Collectors.toList());
        Map<String, List<SceneStructure>> sceneStructureMap = sceneStructures.stream()
                .filter(d -> d.getParentid() != null).collect(Collectors.groupingBy(d -> d.getParentNodeId()));
        firstStructureList.stream().forEach(d -> {
            OpenApiSceneStructureVO sceneStructureVO = JacksonUtil.convertToObj(d, OpenApiSceneStructureVO.class);
            sceneStructureVO.setChildData(buildStructureTree(sceneStructureMap, sceneStructureVO));
            result.add(sceneStructureVO);
        });
        return result;
    }

    /**
     * @Description: 批量获取产品信息
     * @Param: [productKeys, applicationCode]
     * @Return:
     */
    public List<OpenApiSceneProductVO> getSceneProduct(List<String> productKeys, String applicationCode) {
        List<SceneProduct> products = extIotViceProductDAO.getListByAppAndProducts(productKeys, applicationCode);
        List<OpenApiSceneProductVO> result = JacksonUtil.convertToList(products,OpenApiSceneProductVO.class);
        return result;
    }

    /**
     * @Description: 获取计算点号列表
     * @Param: [sceneCode, applicationCode]
     * @Return:
     */
    public List<OpenApiSceneCalculationVO> getSceneCalculation(String sceneCode, String applicationCode) {
        ExtIotScene scene = extIotSceneDAO.selectBySceneCodeAndApplicationCode(sceneCode, applicationCode);
        Assert.notNull(scene, "场景不存在！");
        List<SceneCalculation> sceneCalculations = extIotViceCalculationDAO.selectSceneCalculationListBySceneCode(sceneCode);
        Map<String, String> configMap = extIotViceConfigDAO.selectByTableIdAndApp(applicationCode, TableType.CAL.getCode())
                .stream().filter(Objects::nonNull).collect(Collectors.toMap(ExtIotViceConfig::getTableField, ExtIotViceConfig::getRealField));
        List<OpenApiSceneCalculationVO> result = Lists.newArrayList();
        sceneCalculations.stream().filter(Objects::nonNull).forEach(d -> {
            OpenApiSceneCalculationVO vo = JacksonUtil.convertToObj(d, OpenApiSceneCalculationVO.class);
            vo.setIdentificationMap(TransformUtil.tramsform(d, configMap));
            result.add(vo);
        });
        return result;
    }


    /**
     * @Description: 递归构建出树节点列表
     * @Param: [sceneStructureMap, sceneStructureVO]
     * @Return:
     */
    private List<OpenApiSceneStructureVO> buildStructureTree(Map<String, List<SceneStructure>> sceneStructureMap, OpenApiSceneStructureVO sceneStructureVO) {
        List<SceneStructure> extIotSceneStructures = sceneStructureMap.get(sceneStructureVO.getNodeId());
        if (CollectionUtils.isEmpty(extIotSceneStructures)) {
            return null;
        }
        List<OpenApiSceneStructureVO> sceneStructureVOList = JacksonUtil.convertToList(extIotSceneStructures.stream()
                .sorted(Comparator.comparing(SceneStructure::getOrderNumber)).collect(Collectors.toList()), OpenApiSceneStructureVO.class);
        sceneStructureVO.setChildData(sceneStructureVOList);
        for (OpenApiSceneStructureVO structureVO : sceneStructureVOList) {
            buildStructureTree(sceneStructureMap, structureVO);
        }
        return sceneStructureVOList;
    }

}
